﻿using UnityEngine;
using UnityEngine.UI;
using LuaInterface;

namespace Framework.UGUI
{
    [RequireComponent(typeof(Image))]
    public sealed class SingleImage : MonoBehaviour
    {
        public static SingleImage Get(GameObject go)
        {
            return (null == go) ? null : go.OnceAddComponent<SingleImage>();
        }


        public static SingleImage GetWithPath(GameObject go, string path)
        {
            Transform childTr = go.transform.Find(path);
            return (null == childTr) ? null : childTr.gameObject.OnceAddComponent<SingleImage>();
        }

        public string curImageUrl;
        private GeneralCallBack _loadedCb;
        private Image _image;
        private bool _needLoad;
        private bool _enabled;

        private float textureWidth = 0;
        private float textureHeight = 0;
        public SpriteMeshType spriteMeshType = SpriteMeshType.FullRect;
        private Image ImageComp
        {
            get
            {
                if (null == _image)
                {
                    _image = GetComponent<Image>();
                }

                return _image;
            }
        }

        public void LoadImage(string resPath, LuaFunction luaCb = null, LuaTable luaCbObj = null)
        {
            resPath = FileHelper.GetUnityPath(resPath);
            if (string.IsNullOrEmpty(resPath))
            {
                throw new System.ArgumentNullException("SingleImage.LoadImage, resPath is null or empty!");
            }
            if (null == ImageComp)
            {
                throw new System.ArgumentNullException("SingleImage.LoadImage, ImageComp is null!");
            }
            if (resPath.Equals(curImageUrl))
            {
                if (luaCb != null)
                {
                    if (null != luaCbObj)
                    {
                        luaCb.Call(luaCbObj, textureWidth, textureHeight);
                    }
                    else
                    {
                        luaCb.Call(textureWidth, textureHeight);
                    }
                }
                return;
            }
            curImageUrl = resPath;
            GeneralCallBack.GetOrReUse(ref _loadedCb, luaCb, luaCbObj);
            _needLoad = true;
            _StartLoad();
        }

        [NoToLua]
        public void LoadImage(string resPath, System.Action callback)
        {
	        resPath = FileHelper.GetUnityPath(resPath);
	        if (string.IsNullOrEmpty(resPath))
	        {
		        throw new System.ArgumentNullException("SingleImage.LoadImage, resPath is null or empty!");
	        }
	        if (null == ImageComp)
	        {
		        throw new System.ArgumentNullException("SingleImage.LoadImage, ImageComp is null!");
	        }
	        if (resPath.Equals(curImageUrl))
	        {
		        callback?.Invoke();
		        return;
	        }
	        curImageUrl = resPath;
	        if (_loadedCb != null)
	        {
		        GeneralCallBack.RecycleInst(ref _loadedCb);
            }
	        if (callback != null)
	        {
		        _loadedCb = GeneralCallBack.Get(callback);
            }
	        _needLoad = true;
	        _StartLoad();
        }

        private void _StartLoad()
        {
            if (!_enabled || !_needLoad)
            {
                return;
            }
            SingleUIImageCache.Instance.SetImageSprite(ImageComp, spriteMeshType, curImageUrl,  _OnImageLoaded);
            _needLoad = false;
        }

        private void _OnImageLoaded(float width, float height)
        {
            textureWidth = width;
            textureHeight = height;
            if (null != _loadedCb)
            {
                GeneralCallBack.InvokeAndRecycle(ref _loadedCb, width, height);
            }
        }

        public void UnLoadImage()
        {
            if (string.IsNullOrEmpty(curImageUrl) || null == ImageComp)
            {
                return;
            }
            SingleUIImageCache.Instance.RemoveImageSprite(ImageComp);
            GeneralCallBack.RecycleInst(ref _loadedCb);
            curImageUrl = null;
            _needLoad = false;
        }

        private void OnEnable()
        {
            _enabled = true;
            _StartLoad();
        }

        private void OnDestroy()
        {
            UnLoadImage();
            _enabled = false;
        }
    }
}
